package com.nf.db.handler.list;

import com.nf.db.ResultSetHandler;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * 基于ColumnListHandler与BeanListHandler都有如下的核心重复代码
 * <pre class="code">
 *  List<T> result = new ArrayList<>();
 *  while(rs.next()){
 *      .....
 *      result.add(一条记录的处理);
 *  }
 *  return result
 *  基于下面的两点思考
 *  1. 代码有重复
 *  2.核心逻辑一直，都是处理list
 *  所以，重复的代码放到父类是合理的
 *
 *  此类为什么是抽象的呢？
 *  因为必须让子类冲写handleRow方法，不重写就无法完成表明子类的功能，
 *  因为父类是没有也不可能把完整的功能都实现的
 *
 *
 *  此类的泛型参数T代表着List集合里面成员的类型，因为此类明确的知道返回的就是List集合
 *  不明确的只是集合里面一条记录的类型，也就是成员类型，所以这里把T的含义与ResultSetHandler
 *  中的T含义改到不一致
 * </pre>
 *
 * @param <T>
 */
public abstract class AbstractListHandler<T> implements ResultSetHandler<List<T>> {
    /**
     * final修饰在方法上，意味着这个方法是final的就是最终的意思
     * 也就是说子类不能再改这个方法
     * final放在这里是可以的，你也可以“不放”，理由就是此类已经明确
     * 返回list，子类没有修改handle方法实现的必要
     *
     * @param rs
     * @return
     * @throws SQLException
     */
    @Override
    public final List<T> handle(ResultSet rs) throws SQLException {
        List<T> result = new ArrayList<>();

        while (rs.next()) {
            //处理rs中的一行记录
            T row = handleRow(rs);
            result.add(row);
        }
        return result;
    }

    protected abstract T handleRow(ResultSet rs) throws SQLException;
}
